// mypromise 个人默写版本

class MyPromise {
  static PENDING = 'pending'
  static FULFILLED = 'fulfilled'
  static REJECTED = 'rejected'
  // 构造器
  constructor(exe) {
    this.state = MyPromise.PENDING
    this.value = null
    this.reason = null
    this.onFullledCallBacks = []
    this.onRejectedCallBacks = []

    // 成功的函数
    // 定义resolve函数
    const resolve = (value) => {
      // 如果当前状态为PENDING
      if (this.state === MyPromise.PENDING) {
        // 将状态改为FULFILLED
        this.state = MyPromise.FULFILLED
        // 将value赋值给this.value
        this.value = value
        this.onFullledCallBacks.forEach(fn => fn())
      }
    }


    const reject = (reason) => {
      if (this.state === MyPromise.PENDING) {
        // 将状态改为FULFILLED
        this.state = MyPromise.REJECTED
        // 将value赋值给this.value
        this.reason = reason
        this.onRejectedCallBacks.forEach(fn => fn())
      }
    }

    // 最外部传入的函数
    exe(resolve, reject)
  }


  then(onFulfilled, onRejected) {
    // 类型检测，不为函数时，赋值为默认函数
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
    onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}

    return new MyPromise((resolve, reject) => {
      // 这边都是同步的情况
      if (this.state === MyPromise.FULFILLED) {
        try {
          const result = onFulfilled(this.value)
          resolve(result)
        } catch (error) {
          reject(error)
        }
      }
      if (this.state === MyPromise.REJECTED) {
        try {
          const result = onRejected(this.reason)
          resolve(result)
        }catch (error) {
          reject(error)
        }
        
      }
      // 实现异步的重点，当状态未改变时，放入队列，等待外部触发状态改变时执行
      if (this.state === MyPromise.PENDING) {
        this.onFullledCallBacks.push(() => {
          try {
            const result = onFulfilled(this.value)
            resolve(result)
          } catch (error) {
            reject(error)
          }
        })
        this.onRejectedCallBacks.push(() => {
          try {
            const result = onRejected(this.reason)
            resolve(result)
          }catch (error) {
            reject(error)
          }
        })
      }
    })
  }

  // 只含有onRejected的then方法
  catch(onRejected) {
    return this.then(null, onRejected)
  }


  // 静态方法all
  static all(promiseArr) {
    // 省略参数判断，默认为数组
    return new MyPromise((resovle, reject) => {
      let count = 0
      let result = []
      promiseArr.forEach((promise) => {
        promise.then((data) => {
          count++
          result.push(data)
          if (count === promiseArr.length) {
            resovle(result)
          }
        }, (reson) => {
          reject(reson)
        })
      })
    })
  }
}


const p1 = new MyPromise((resolve, reject) => {
  resolve('成功')
})
console.log('成功回调', p1)
const p2 = new MyPromise((resolve, reject) => {
  reject('失败')
})
console.log('失败回调', p2)

const p3 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('成功')
  }, 2000)
}).then((res) => {
  console.log('成功回调', res)
})
const p4 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    reject('失败')
  }, 2500)
}).then((res) => {
  console.log('成功回调', res)
}).catch((err) => {
  console.log('catch', err)
})


const p5 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('成功')
  }, 3000)
})

const p6 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('成功')
  }, 2000)
})

MyPromise.all([p5, p6]).then((res) => {
  console.log('all', res)
})